<template>
  <div>
    <div class="jsoneditor-vue" :style="editorStyle"></div>
  </div>
</template>

<script>
import JsonEditor from 'jsoneditor'
import 'jsoneditor/dist/jsoneditor.css'
export default {
  name: 'vueJsonEditor',
  props: {
    value: [String, Number, Object, Array],
    showBtns: [Boolean],
    expandedOnStart: {
      type: Boolean,
      default: false
    },
    mode: {
      type: String,
      default: 'tree'
    },
    modes: {
      type: Array,
      default: () => ['tree', 'code', 'form', 'text', 'view']
    },
    editorStyle: {
      type: Object,
      default: () => {}
    }
  },
  watch: {
    value: {
      immediate: true,
      async handler (val) {
        if (!this.internalChange) {
          await this.setEditor(val)

          this.expandAll()
        }
      },
      deep: true
    }
  },
  data () {
    return {
      editor: null,
      error: false,
      json: this.value,
      internalChange: false,
      expandedModes: ['tree', 'view', 'form']
    }
  },
  mounted () {
    let self = this

    let options = {
      mode: this.mode,
      modes: this.modes, // allowed modes
      onChange () {
        console.log('Json editor change')
        try {
          let json = self.editor.get()
          self.json = json
          self.$emit('json-change', json)
          self.internalChange = true
          self.$emit('input', json)
          self.$nextTick(function () {
            self.internalChange = false
          })
        } catch (e) {
          self.$emit('has-error', e)
        }
      },
      onModeChange () {
        self.expandAll()
      }
    }

    this.editor = new JsonEditor(
      this.$el.querySelector('.jsoneditor-vue'),
      options,
      this.json
    )
  },
  methods: {
    expandAll () {
      if (
        this.expandedOnStart &&
        this.expandedModes.includes(this.editor.getMode())
      ) {
        this.editor.expandAll()
      }
    },

    onSave () {
      this.$emit('json-save', this.json)
    },

    async setEditor (value) {
      if (this.editor) this.editor.set(value)
    }
  }
}
</script>
<style lang="scss">
  .jsoneditor-vue{
    .jsoneditor-contextmenu{
      z-index: 5;
    }
  }
</style>
